package com.cryptoneedle.center.mapping.service;

import com.cryptoneedle.center.common.entity.mapping.MappingColumn;
import com.cryptoneedle.center.common.entity.mapping.MappingTable;
import com.cryptoneedle.center.common.enums.MappingFieldType;
import com.cryptoneedle.center.common.key.TableKey;
import com.cryptoneedle.center.mapping.vo.MappingTableConfigVo;
import com.google.common.collect.Maps;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

/**
 * <p>description:  </p>
 *
 * @author CryptoNeedle
 * @date 2025-09-26
 */
@Service
@Slf4j
public class MappingService {

    @Resource
    private MappingTableService mappingTableService;

    @Resource
    private MappingColumnService mappingColumnService;

    @Transactional(rollbackFor = Exception.class)
    public void configMappingTable(MappingTableConfigVo mappingTableConfigVo) {
        TableKey tableKey = mappingTableConfigVo.getTableKey();
        Boolean mappingTableFlag = mappingTableConfigVo.getMappingTableFlag();
        List<MappingTableConfigVo.ColumnConfig> columnConfigList = mappingTableConfigVo.getColumnConfigList();

        // 获取表
        MappingTable mappingTable = mappingTableService.getById(tableKey);
        if (mappingTable == null) {
            throw new RuntimeException("Table not found");
        }

        // 标准表标记
        mappingTable.setMappingTableFlag(mappingTableFlag);
        mappingTableService.save(mappingTable);

        // 获取字段
        List<MappingColumn> mappingColumnList = mappingColumnService.listByTable(tableKey);

        // 设置为标准表
        if (mappingTableFlag) {
            if (columnConfigList == null || columnConfigList.isEmpty()) {
                throw new RuntimeException("Column config is empty");
            }

            Map<String, MappingColumn> mappingColumnMap = Maps.uniqueIndex(mappingColumnList, MappingColumn::getColumnName);
            Map<String, MappingTableConfigVo.ColumnConfig> columnConfigMap = Maps.uniqueIndex(columnConfigList, MappingTableConfigVo.ColumnConfig::getColumnName);

            // 字段排序
            AtomicLong mappingSequence = new AtomicLong(1);
            // columnConfigList 排序规则
            Map<MappingFieldType, Integer> typeOrder = new HashMap<>();
            typeOrder.put(MappingFieldType.MAPPING_CODE, 1);
            typeOrder.put(MappingFieldType.STANDARD, 2);
            typeOrder.put(MappingFieldType.MAPPING_COMMENT, 3);
            typeOrder.put(MappingFieldType.IGNORE, 4);
            columnConfigList.sort(Comparator.comparing(config -> typeOrder.getOrDefault(config.getMappingFieldType(), Integer.MAX_VALUE)));

            // 配置提交的配置列
            columnConfigList.forEach(configColumn -> {

                MappingColumn mappingColumn = mappingColumnMap.get(configColumn.getColumnName());
                if (mappingColumn != null) {
                    MappingFieldType mappingFieldType = configColumn.getMappingFieldType();
                    if (MappingFieldType.MAPPING_CODE.equals(mappingFieldType) || MappingFieldType.STANDARD.equals(mappingFieldType)) {
                        mappingColumn.setMappingSequence(mappingSequence.getAndIncrement());
                    } else {
                        mappingColumn.setMappingSequence(null);
                    }
                    mappingColumn.setMappingFieldType(mappingFieldType);
                }
            });

            // 防止提交的配置列不完整
            mappingColumnList.forEach(mappingColumn -> {
                if (mappingColumn.getMappingFieldType() == null || !columnConfigMap.containsKey(mappingColumn.getColumnName())) {
                    mappingColumn.setMappingSequence(null);
                    mappingColumn.setMappingFieldType(MappingFieldType.IGNORE);
                }
            });
        } else {
            // 取消设置标准表
            mappingColumnList.forEach(mappingColumn -> {
                mappingColumn.setMappingSequence(null);
                mappingColumn.setMappingFieldType(null);
            });
        }

        mappingColumnService.saveAll(mappingColumnList);
    }
}